package com.zenithmind.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.chat.mapper.ChatPrivateSessionUserMapper;
import com.zenithmind.chat.pojo.entity.ChatPrivateSessionUser;
import com.zenithmind.chat.pojo.vo.ChatPrivateSessionUserVO;
import com.zenithmind.chat.service.ChatPrivateSessionUserService;
import com.zenithmind.common.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 私聊会话用户关系服务实现类 - 遵循单一职责原则
 * 只负责私聊会话用户关系的业务逻辑处理
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatPrivateSessionUserServiceImpl extends ServiceImpl<ChatPrivateSessionUserMapper, ChatPrivateSessionUser> 
        implements ChatPrivateSessionUserService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createSessionUser(String sessionId, String userId) {
        if (sessionId == null || sessionId.trim().isEmpty()) {
            throw new BusinessException("会话ID不能为空");
        }
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        // 检查关系是否已存在
        if (isUserInSession(sessionId, userId)) {
            throw new BusinessException("用户已在该会话中");
        }
        
        ChatPrivateSessionUser sessionUser = new ChatPrivateSessionUser();
        sessionUser.setSessionId(sessionId);
        sessionUser.setUserId(userId);
        sessionUser.setLastAccessTime(LocalDateTime.now());
        sessionUser.setLastReadTime(LocalDateTime.now());
        sessionUser.setUnreadCount(0);
        sessionUser.setIsTop(false);
        sessionUser.setIsMuted(false);
        sessionUser.setIsArchived(false);
        sessionUser.setCreateTime(LocalDateTime.now());
        sessionUser.setUpdateTime(LocalDateTime.now());
        
        save(sessionUser);
        
        log.info("创建会话用户关系成功，会话ID: {}, 用户ID: {}, 关系ID: {}", 
                sessionId, userId, sessionUser.getId());
        
        return sessionUser.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchCreateSessionUsers(String sessionId, List<String> userIds) {
        if (sessionId == null || sessionId.trim().isEmpty()) {
            throw new BusinessException("会话ID不能为空");
        }
        if (userIds == null || userIds.isEmpty()) {
            throw new BusinessException("用户ID列表不能为空");
        }
        
        for (String userId : userIds) {
            if (!isUserInSession(sessionId, userId)) {
                createSessionUser(sessionId, userId);
            }
        }
        
        log.info("批量创建会话用户关系成功，会话ID: {}, 用户数量: {}", sessionId, userIds.size());
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteSessionUser(String sessionId, String userId) {
        if (sessionId == null || sessionId.trim().isEmpty()) {
            throw new BusinessException("会话ID不能为空");
        }
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getSessionId, sessionId)
                   .eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0);
        
        ChatPrivateSessionUser sessionUser = getOne(queryWrapper);
        if (sessionUser == null) {
            throw new BusinessException("会话用户关系不存在");
        }
        
        // 逻辑删除
        sessionUser.setIsDeleted(1);
        sessionUser.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(sessionUser);
        
        if (result) {
            log.info("删除会话用户关系成功，会话ID: {}, 用户ID: {}", sessionId, userId);
        }
        
        return result;
    }

    @Override
    public List<ChatPrivateSessionUserVO> getUsersBySessionId(String sessionId) {
        if (sessionId == null || sessionId.trim().isEmpty()) {
            throw new BusinessException("会话ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getSessionId, sessionId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0)
                   .orderByDesc(ChatPrivateSessionUser::getLastAccessTime);
        
        List<ChatPrivateSessionUser> sessionUsers = list(queryWrapper);
        return sessionUsers.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public List<ChatPrivateSessionUserVO> getSessionsByUserId(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0)
                   .orderByDesc(ChatPrivateSessionUser::getLastAccessTime);
        
        List<ChatPrivateSessionUser> sessionUsers = list(queryWrapper);
        return sessionUsers.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public ChatPrivateSessionUserVO getSessionUser(String sessionId, String userId) {
        if (sessionId == null || sessionId.trim().isEmpty()) {
            throw new BusinessException("会话ID不能为空");
        }
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getSessionId, sessionId)
                   .eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0);
        
        ChatPrivateSessionUser sessionUser = getOne(queryWrapper);
        if (sessionUser == null) {
            throw new BusinessException("会话用户关系不存在");
        }
        
        return convertToVO(sessionUser);
    }

    @Override
    public Boolean isUserInSession(String sessionId, String userId) {
        if (sessionId == null || sessionId.trim().isEmpty() || userId == null || userId.trim().isEmpty()) {
            return false;
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getSessionId, sessionId)
                   .eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0);
        
        return count(queryWrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLastAccessTime(String sessionId, String userId, LocalDateTime lastAccessTime) {
        return updateSessionUserField(sessionId, userId, "lastAccessTime", lastAccessTime);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLastAccessTimeToNow(String sessionId, String userId) {
        return updateLastAccessTime(sessionId, userId, LocalDateTime.now());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUnreadCount(String sessionId, String userId, Integer unreadCount) {
        return updateSessionUserField(sessionId, userId, "unreadCount", unreadCount);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean incrementUnreadCount(String sessionId, String userId) {
        ChatPrivateSessionUser sessionUser = getSessionUserEntity(sessionId, userId);
        int currentCount = sessionUser.getUnreadCount() != null ? sessionUser.getUnreadCount() : 0;
        return updateUnreadCount(sessionId, userId, currentCount + 1);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean clearUnreadCount(String sessionId, String userId) {
        return updateUnreadCount(sessionId, userId, 0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchClearUnreadCount(List<String> sessionIds, String userId) {
        if (sessionIds == null || sessionIds.isEmpty()) {
            return true;
        }
        
        for (String sessionId : sessionIds) {
            clearUnreadCount(sessionId, userId);
        }
        
        log.info("批量清零未读消息数成功，用户ID: {}, 会话数量: {}", userId, sessionIds.size());
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTopStatus(String sessionId, String userId, Boolean isTop) {
        return updateSessionUserField(sessionId, userId, "isTop", isTop);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateMuteStatus(String sessionId, String userId, Boolean isMuted) {
        return updateSessionUserField(sessionId, userId, "isMuted", isMuted);
    }

    @Override
    public List<ChatPrivateSessionUserVO> getTopSessionsByUserId(String userId) {
        return getSessionsByUserIdAndCondition(userId, "isTop", true);
    }

    @Override
    public List<ChatPrivateSessionUserVO> getMutedSessionsByUserId(String userId) {
        return getSessionsByUserIdAndCondition(userId, "isMuted", true);
    }

    @Override
    public Long countTotalUnreadByUserId(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0)
                   .select(ChatPrivateSessionUser::getUnreadCount);
        
        List<ChatPrivateSessionUser> sessionUsers = list(queryWrapper);
        return sessionUsers.stream()
                          .mapToLong(su -> su.getUnreadCount() != null ? su.getUnreadCount() : 0)
                          .sum();
    }

    @Override
    public Integer getUnreadCountBySession(String sessionId, String userId) {
        ChatPrivateSessionUser sessionUser = getSessionUserEntity(sessionId, userId);
        return sessionUser.getUnreadCount() != null ? sessionUser.getUnreadCount() : 0;
    }

    @Override
    public List<ChatPrivateSessionUserVO> getActiveSessionsByUserId(String userId, Integer limit) {
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0)
                   .orderByDesc(ChatPrivateSessionUser::getLastAccessTime)
                   .last("LIMIT " + (limit != null ? limit : 10));
        
        List<ChatPrivateSessionUser> sessionUsers = list(queryWrapper);
        return sessionUsers.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLastReadTime(String sessionId, String userId, LocalDateTime lastReadTime) {
        return updateSessionUserField(sessionId, userId, "lastReadTime", lastReadTime);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLastReadTimeToNow(String sessionId, String userId) {
        return updateLastReadTime(sessionId, userId, LocalDateTime.now());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateLastAccessTime(List<String> sessionIds, String userId, LocalDateTime lastAccessTime) {
        if (sessionIds == null || sessionIds.isEmpty()) {
            return true;
        }
        
        for (String sessionId : sessionIds) {
            updateLastAccessTime(sessionId, userId, lastAccessTime);
        }
        
        log.info("批量更新最后访问时间成功，用户ID: {}, 会话数量: {}", userId, sessionIds.size());
        
        return true;
    }

    @Override
    public List<String> getUserIdsBySessionId(String sessionId) {
        if (sessionId == null || sessionId.trim().isEmpty()) {
            throw new BusinessException("会话ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getSessionId, sessionId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0)
                   .select(ChatPrivateSessionUser::getUserId);
        
        List<ChatPrivateSessionUser> sessionUsers = list(queryWrapper);
        return sessionUsers.stream()
                          .map(ChatPrivateSessionUser::getUserId)
                          .collect(Collectors.toList());
    }

    @Override
    public List<String> getSessionIdsByUserId(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0)
                   .select(ChatPrivateSessionUser::getSessionId);
        
        List<ChatPrivateSessionUser> sessionUsers = list(queryWrapper);
        return sessionUsers.stream()
                          .map(ChatPrivateSessionUser::getSessionId)
                          .collect(Collectors.toList());
    }

    @Override
    public Boolean hasCommonSession(String userId1, String userId2) {
        List<String> sessions1 = getSessionIdsByUserId(userId1);
        List<String> sessions2 = getSessionIdsByUserId(userId2);
        
        return sessions1.stream().anyMatch(sessions2::contains);
    }

    @Override
    public List<ChatPrivateSessionUserVO> getCommonSessions(String userId1, String userId2) {
        List<String> sessions1 = getSessionIdsByUserId(userId1);
        List<String> sessions2 = getSessionIdsByUserId(userId2);
        
        List<String> commonSessionIds = sessions1.stream()
                                               .filter(sessions2::contains)
                                               .collect(Collectors.toList());
        
        return commonSessionIds.stream()
                              .map(sessionId -> getSessionUser(sessionId, userId1))
                              .collect(Collectors.toList());
    }

    @Override
    public Long countSessionsByUserId(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0);
        
        return count(queryWrapper);
    }

    @Override
    public Long countUsersBySessionId(String sessionId) {
        if (sessionId == null || sessionId.trim().isEmpty()) {
            throw new BusinessException("会话ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getSessionId, sessionId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0);
        
        return count(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer cleanupInactiveSessionUsers(Integer inactiveDays) {
        LocalDateTime inactiveTime = LocalDateTime.now().minusDays(inactiveDays);
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getIsDeleted, 0)
                   .lt(ChatPrivateSessionUser::getLastAccessTime, inactiveTime);
        
        List<ChatPrivateSessionUser> inactiveSessionUsers = list(queryWrapper);
        
        for (ChatPrivateSessionUser sessionUser : inactiveSessionUsers) {
            sessionUser.setIsDeleted(1);
            sessionUser.setUpdateTime(LocalDateTime.now());
            updateById(sessionUser);
        }
        
        log.info("清理不活跃会话用户关系完成，清理数量: {}", inactiveSessionUsers.size());
        
        return inactiveSessionUsers.size();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean archiveSessionUser(String sessionId, String userId, Boolean isArchived) {
        return updateSessionUserField(sessionId, userId, "isArchived", isArchived);
    }

    @Override
    public List<ChatPrivateSessionUserVO> getArchivedSessionsByUserId(String userId) {
        return getSessionsByUserIdAndCondition(userId, "isArchived", true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchArchiveSessionUsers(List<String> sessionIds, String userId, Boolean isArchived) {
        if (sessionIds == null || sessionIds.isEmpty()) {
            return true;
        }
        
        for (String sessionId : sessionIds) {
            archiveSessionUser(sessionId, userId, isArchived);
        }
        
        log.info("批量归档会话用户关系成功，用户ID: {}, 会话数量: {}, 归档状态: {}", 
                userId, sessionIds.size(), isArchived);
        
        return true;
    }

    /**
     * 获取会话用户实体
     */
    private ChatPrivateSessionUser getSessionUserEntity(String sessionId, String userId) {
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getSessionId, sessionId)
                   .eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0);
        
        ChatPrivateSessionUser sessionUser = getOne(queryWrapper);
        if (sessionUser == null) {
            throw new BusinessException("会话用户关系不存在");
        }
        
        return sessionUser;
    }

    /**
     * 更新会话用户字段
     */
    private Boolean updateSessionUserField(String sessionId, String userId, String fieldName, Object value) {
        ChatPrivateSessionUser sessionUser = getSessionUserEntity(sessionId, userId);
        
        // 根据字段名设置值（这里简化处理，实际应该使用反射或其他方式）
        switch (fieldName) {
            case "lastAccessTime":
                sessionUser.setLastAccessTime((LocalDateTime) value);
                break;
            case "lastReadTime":
                sessionUser.setLastReadTime((LocalDateTime) value);
                break;
            case "unreadCount":
                sessionUser.setUnreadCount((Integer) value);
                break;
            case "isTop":
                sessionUser.setIsTop((Boolean) value);
                break;
            case "isMuted":
                sessionUser.setIsMuted((Boolean) value);
                break;
            case "isArchived":
                sessionUser.setIsArchived((Boolean) value);
                break;
            default:
                throw new BusinessException("不支持的字段: " + fieldName);
        }
        
        sessionUser.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(sessionUser);
        
        if (result) {
            log.debug("更新会话用户字段成功，会话ID: {}, 用户ID: {}, 字段: {}", 
                    sessionId, userId, fieldName);
        }
        
        return result;
    }

    /**
     * 根据条件查询用户会话
     */
    private List<ChatPrivateSessionUserVO> getSessionsByUserIdAndCondition(String userId, String fieldName, Object value) {
        if (userId == null || userId.trim().isEmpty()) {
            throw new BusinessException("用户ID不能为空");
        }
        
        LambdaQueryWrapper<ChatPrivateSessionUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatPrivateSessionUser::getUserId, userId)
                   .eq(ChatPrivateSessionUser::getIsDeleted, 0)
                   .orderByDesc(ChatPrivateSessionUser::getLastAccessTime);
        
        // 根据字段名添加条件（这里简化处理）
        switch (fieldName) {
            case "isTop":
                queryWrapper.eq(ChatPrivateSessionUser::getIsTop, value);
                break;
            case "isMuted":
                queryWrapper.eq(ChatPrivateSessionUser::getIsMuted, value);
                break;
            case "isArchived":
                queryWrapper.eq(ChatPrivateSessionUser::getIsArchived, value);
                break;
        }
        
        List<ChatPrivateSessionUser> sessionUsers = list(queryWrapper);
        return sessionUsers.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    /**
     * 转换为VO
     */
    private ChatPrivateSessionUserVO convertToVO(ChatPrivateSessionUser sessionUser) {
        ChatPrivateSessionUserVO vo = new ChatPrivateSessionUserVO();
        vo.setId(sessionUser.getId());
        vo.setSessionId(sessionUser.getSessionId());
        vo.setUserId(sessionUser.getUserId());
        vo.setLastAccessTime(sessionUser.getLastAccessTime());
        vo.setLastReadTime(sessionUser.getLastReadTime());
        vo.setUnreadCount(sessionUser.getUnreadCount());
        vo.setIsTop(sessionUser.getIsTop());
        vo.setIsMuted(sessionUser.getIsMuted());
        vo.setIsArchived(sessionUser.getIsArchived());
        vo.setCreateTime(sessionUser.getCreateTime());
        vo.setUpdateTime(sessionUser.getUpdateTime());
        return vo;
    }
}
